<?php

namespace App\Console;

use App\Jobs\UpdatePaperBtCount;
use App\Models\PartCompany;
use App\Models\PartCompanyClassify;
use App\Models\ProjectClassify;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class Kernel extends ConsoleKernel
{
    const START_TIME = '00:30'; //删除案卷、卷内、卷内PDF分表空表 (第一种：空表)
    const REDIS_KEY  = 'UpdatePaperBtCount';

    /**
     * @param Schedule $schedule
     *
     * @author: lxk
     * @date: 2023/8/26 17:08
     */
    protected function schedule(Schedule $schedule)
    {
        /**
         * 【第1步】
         * 删除案卷、卷内、卷内PDF分表空表
         * 第一种：空表
         */
        $schedule->call(function () {
            info('第1步：空表');
            $idsInfo            = self::getPartAndProjectClassifyIds();
            $partCompanyIds     = $idsInfo['part_company_ids'];
            $projectClassifyIds = $idsInfo['project_classify_ids'];
            foreach ($partCompanyIds as $partCompanyId) {
                foreach ($projectClassifyIds as $projectClassifyId) {
                    $table1 = "book_titles_{$partCompanyId}_{$projectClassifyId}";
                    $table2 = "book_catalogs_{$partCompanyId}_{$projectClassifyId}";
                    $table3 = "book_catalog_pdfs_{$partCompanyId}_{$projectClassifyId}";
                    if (Schema::hasTable($table1)) {
                        $btCount1 = DB::table($table1)->whereNull('deleted_at')->count('id'); //有效数据
                        $btCount2 = DB::table($table1)->count('id'); //全部数据
                        if (empty($btCount1) || empty($btCount2)) {
                            Schema::drop($table1);
                        }
                    }
                    if (Schema::hasTable($table2)) {
                        $bcCount1 = DB::table($table2)->whereNull('deleted_at')->count('id'); //有效数据
                        $bcCount2 = DB::table($table2)->count('id'); //全部数据
                        if (empty($bcCount1) || empty($bcCount2)) { //如果分表没数据，删除分表
                            Schema::drop($table2);
                        }
                    }
                    if (Schema::hasTable($table3)) {
                        $bpCount = DB::table($table3)->count('id'); //全部数据
                        if (empty($bpCount)) {
                            Schema::drop($table3);
                        }
                    }
                }
            }
        })->dailyAt(Carbon::parse(self::START_TIME)->addMinutes(2)->format('H:i'))->name('step1')->withoutOverlapping();

        /**
         * 【第2步】
         * 删除案卷、卷内、卷内PDF分表空表
         * 第二种：项目分类被删除，分表作废
         */
        $schedule->call(function () {
            info('第2步：项目分类被删除，分表作废');
            $idsInfo                      = self::getPartAndProjectClassifyIds();
            $partCompanyIds               = $idsInfo['part_company_ids'];
            $hadSoftDelProjectClassifyIds = ProjectClassify::onlyTrashed()->pluck('id')->toArray(); //被软删除的项目分类数据
            foreach ($hadSoftDelProjectClassifyIds as $hadSoftDelProjectClassifyId) {
                foreach ($partCompanyIds as $partCompanyId) {
                    $table1 = "book_titles_{$partCompanyId}_{$hadSoftDelProjectClassifyId}";
                    $table2 = "book_catalogs_{$partCompanyId}_{$hadSoftDelProjectClassifyId}";
                    $table3 = "book_catalog_pdfs_{$partCompanyId}_{$hadSoftDelProjectClassifyId}";
                    if (Schema::hasTable($table1)) {
                        Schema::drop($table1);
                    }
                    if (Schema::hasTable($table2)) {
                        Schema::drop($table2);
                    }
                    if (Schema::hasTable($table3)) {
                        Schema::drop($table3);
                    }
                }
            }
        })->dailyAt(Carbon::parse(self::START_TIME)->addMinutes(10)->format('H:i'))->name('step2')->withoutOverlapping();

        /**
         * 【第3步】
         * 删除案卷、卷内、卷内PDF分表空表
         * 第三种：参建单位被删除，分表作废
         */
        $schedule->call(function () {
            info('第3步：参建单位被删除，分表作废');
            $idsInfo                  = self::getPartAndProjectClassifyIds();
            $projectClassifyIds       = $idsInfo['project_classify_ids'];
            $hadSoftDelPartCompanyIds = PartCompany::onlyTrashed()->pluck('id')->toArray(); //被软删除的参见单位数据
            foreach ($hadSoftDelPartCompanyIds as $hadSoftDelPartCompanyId) {
                foreach ($projectClassifyIds as $projectClassifyId) {
                    $table1 = "book_titles_{$hadSoftDelPartCompanyId}_{$projectClassifyId}";
                    $table2 = "book_catalogs_{$hadSoftDelPartCompanyId}_{$projectClassifyId}";
                    $table3 = "book_catalog_pdfs_{$hadSoftDelPartCompanyId}_{$projectClassifyId}";
                    if (Schema::hasTable($table1)) {
                        Schema::drop($table1);
                    }
                    if (Schema::hasTable($table2)) {
                        Schema::drop($table2);
                    }
                    if (Schema::hasTable($table3)) {
                        Schema::drop($table3);
                    }
                }
            }
        })->dailyAt(Carbon::parse(self::START_TIME)->addMinutes(15)->format('H:i'))->name('step3')->withoutOverlapping();

        /**
         * 【第4步】
         *  统计各参建单位的案卷数据 everyMinute();
         *  定时任务虽然每分钟都执行，但是在任务内部进一步给出了执行的条件
         */
        $schedule->job(new UpdatePaperBtCount(self::REDIS_KEY))->everyTwoMinutes(2)->name('NoRepeatUpdate')->withoutOverlapping();

        /**
         * 【第5步】
         *  清除 REDIS_KEY
         */
        $schedule->call(function () {
            redis()->del(self::REDIS_KEY);
            PartCompany::query()->update(['need_update_statistic' => 1]); //每天早上8点全部更新为1，为明天统计做准备
        })->dailyAt('08:00')->name('step5')->withoutOverlapping();

    }

    /**
     * 获取有效的参见单位和项目分类
     * ->where('part_company_id', '!=', 28) //part_company_id=28的数据表数据量大，单独处理
     * @return array
     * @author: lxk
     * @date: 2024-10-24 14:24
     */
    public static function getPartAndProjectClassifyIds() : array
    {
        $partCompanyIds = PartCompanyClassify::query()
            ->distinct()
            ->orderBy('part_company_id')
            ->pluck('part_company_id')
            ->toArray();

        $projectClassifyIds = PartCompanyClassify::query()->distinct()
            ->orderBy('project_classify_id')
            ->pluck('project_classify_id')
            ->toArray();

        return [
            'part_company_ids'     => $partCompanyIds,
            'project_classify_ids' => $projectClassifyIds,
        ];
    }

}
